package luatask

import (
	"bytes"
	"io/ioutil"
	"strings"

	"gitee.com/haodreams/golib/logs"
	"github.com/robfig/cron"
	lua "github.com/yuin/gopher-lua"
)

//MapSet .
func MapSet(l *lua.LState) int {
	n := l.GetTop()
	if n < 2 {
		return 0
	}
	key := l.CheckString(1)
	value := l.Get(2)
	boss.Set(key, value)
	return 0
}

//MapGet .
func MapGet(l *lua.LState) int {
	n := l.GetTop()
	if n < 1 {
		return 0
	}

	key := l.CheckString(1)
	value := boss.Get(key)
	l.Push(value)
	return 1
}

//InitSyncLua 初始化同步的任务
/**
 * @description:
 * @param {string} path
 * @param {func} initFunc 并发执行时，重新初始化脚本时的回调初始化函数
 * @return {*}
 */
func InitSyncLua(path string, initFunc func(l *lua.LState)) {
	tasks := loadLuaFile(path, "sync.csv", initFunc)
	array := make([]*Task, 0)
	kv := map[string]*Tasks{}
	for _, task := range tasks {
		if ts, ok := kv[task.Time]; ok {
			ts.tasks = append(ts.tasks, task)
		} else {
			ts = new(Tasks)
			ts.Time = task.Time
			ts.tasks = append(ts.tasks, task)
			kv[task.Time] = ts
		}
		array = append(array, task)
	}

	boss.SyncTask.array = array
	boss.SyncTask.taskMap = kv
	boss.syncCron = cron.New(cron.WithSeconds()) //

	for _, tasks := range kv {
		if tasks.Time == "init" {
			go tasks.Run()
			continue
		}
		id, err := boss.syncCron.AddJob(tasks.Time, tasks)
		if err != nil {
			logs.Error(err.Error())
			continue
		}
		tasks.ID = int(id)
	}
	boss.syncCron.Start()
}

//InitAsynLua 初始化异步任务
func InitAsynLua(path string, initCallback func(l *lua.LState)) {
	tasks := loadLuaFile(path, "async.csv", initCallback)
	boss.AsyncTask.tasks = append(boss.AsyncTask.tasks, tasks...)
	boss.asyncCron = cron.New(cron.WithSeconds()) //

	for _, task := range boss.AsyncTask.tasks {
		if task.Time == "init" {
			go task.Run()
			continue
		}
		id, err := boss.asyncCron.AddJob(task.Time, task)
		task.id = int(id)
		if err != nil {
			logs.Error(err.Error())
			continue
		}
	}

	boss.asyncCron.Start()
}

//loadLuaFile 初始化lua
func loadLuaFile(path string, fileName string, initCallback func(l *lua.LState)) (tasks []*Task) {
	data, err := ioutil.ReadFile(path + fileName)
	if err != nil {
		return
	}

	buf := bytes.NewBuffer(data)
	for line, err := buf.ReadString('\n'); err == nil || len(line) > 0; line, err = buf.ReadString('\n') {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}
		if line[0] == '#' {
			continue
		}

		//time,lua,desc
		ss := strings.Split(line, ",")
		for i := range ss {
			ss[i] = strings.TrimSpace(ss[i])
		}

		if len(ss) < 2 {
			continue
		}

		task := new(Task)
		task.Time = ss[0]
		//,是关键字段
		task.Time = strings.ReplaceAll(task.Time, "|", ",")
		task.Path = path + ss[1]

		if len(ss) > 2 {
			task.Desc = ss[2]
		}
		l := lua.NewState()
		//luastring.InitLuaString(l)
		//InitLuaDB(l)
		if initCallback != nil {
			initCallback(l)
		}
		task.initCallback = initCallback
		err := l.DoFile(task.Path)
		if err != nil {
			logs.Error("Load lua file error,", err.Error())
			continue
		}
		task.l = l
		tasks = append(tasks, task)
	}
	return
}
